# -*- coding: utf-8 -*- 

'''
Tutorial of keras: https://www.tensorflow.org/tutorials/keras/basic_regression
Created on 2018年8月24日

@author: leehe

This tutorial use The Boston Housing Prices dataset, which locate at:
    https://s3.amazonaws.com/keras-datasets/boston_housing.npz
'''

import tensorflow as tf
from tensorflow import keras

import numpy as np
import os

import matplotlib.pyplot as plt
import pandas as pd

boston_housing = keras.datasets.boston_housing

(train_data, train_labels), (test_data, test_labels) = boston_housing.load_data(
    path=os.path.join(os.environ['KERAS_DATASETS'],'boston_housing.npz')) 

# shuffle train data
order = np.argsort(np.random.random(train_labels.shape))
train_data = train_data[order]
train_labels = train_labels[order]

# Use the pandas library to display the first few rows of the dataset in a nicely formatted table
column_names = ['CRIM', 'ZN', 'INDUS', 'CHAS', 'NOX', 'RM', 'AGE', 'DIS', 'RAD',
                'TAX', 'PTRATIO', 'B', 'LSTAT']

df = pd.DataFrame(train_data, columns=column_names)
print(df.head(n=10))

# Normalize features
mean = train_data.mean(axis=0)
std = train_data.std(axis=0)
train_data = (train_data - mean) / std
test_data = (test_data - mean) / std


def build_model():
    model = keras.Sequential([
      keras.layers.Dense(64, activation=tf.nn.relu,
                       input_shape=(train_data.shape[1],)),
      keras.layers.Dense(64, activation=tf.nn.relu),
      keras.layers.Dense(1)
    ])

    optimizer = tf.train.RMSPropOptimizer(0.001)

    model.compile(loss='mse',
                  optimizer=optimizer,
                  metrics=['mae'])
    return model


model = build_model()
model.summary()


# Display training progress by printing a single dot for each completed epoch.
class PrintDot(keras.callbacks.Callback):

    def on_epoch_end(self, epoch, logs):
        if epoch % 100 == 0: print('')
        print('.', end='')


EPOCHS = 500

# Store training stats
history = model.fit(train_data, train_labels, epochs=EPOCHS,
                    validation_split=0.2, verbose=0,
                    callbacks=[PrintDot()])


def plot_history(history):
    plt.figure()
    plt.xlabel('Epoch')
    plt.ylabel('Mean Abs Error [1000$]')
    plt.plot(history.epoch, np.array(history.history['mean_absolute_error']),
             label='Train Loss')
    plt.plot(history.epoch, np.array(history.history['val_mean_absolute_error']),
             label='Val loss')
    plt.legend()
    plt.ylim([0, 5])


plot_history(history)

test_predictions = model.predict(test_data).flatten()
test_errors = test_predictions - test_labels
r = []
for i in range(len(test_labels)):
    r.append([test_labels[i], test_predictions[i], test_errors[i]])
    
print('\n\nPrediction')
for i in range(len(r)):
    print(r[i])

plt.show()
